package comprasdiretas.beans;

import java.math.BigDecimal;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import comprasdiretas.ejb.ItemControllerLocal;
import comprasdiretas.ejb.PedidoControllerLocal;
import comprasdiretas.entity.ItemEntity;
import comprasdiretas.entity.PedidoEntity;
import comprasdiretas.entity.PedidoEntityPK;
import comprasdiretas.exception.ObjetoJaCadastradoException;
import comprasdiretas.exception.ParametroNullException;
import comprasdiretas.util.Extenso;
import comprasdiretas.util.ItemDetalhes;

public class PedidoBean {
	private int numPedido;
	private String processo;
	private String fonte;
	private String ptres;
	private Date data;
	private String elementoDespesa;
	private HashMap<String,ItemDetalhes> itens;
	private List<ItemDetalhes> listaItens;
	
	private int idItemAtual;
	private String especificacaoAtual;
	private String codSIASGAtual;
	private String unidadeAtual;
	private ItemEntity itemEntitySelecionado;
	private ItemDetalhes itemDetalheSelecionado;
	private BigDecimal quantidadeItemAtual;
	private BigDecimal precoItemAtual;
	
	private boolean editavel=true;

	@EJB
	private PedidoControllerLocal pedidoController;
	@EJB
	private ItemControllerLocal itemController;
	
	
	private boolean itemFoiPesquisado = false;


	public PedidoBean(){
		this.data=new Date(System.currentTimeMillis());
	}


	public int getNumPedido() {
		return numPedido;
	}



	public void setNumPedido(int numPedido) {
		this.numPedido = numPedido;
	}



	public String getProcesso() {
		return processo;
	}



	public void setProcesso(String processo) {
		this.processo = processo;
	}



	public String getFonte() {
		return fonte;
	}



	public void setFonte(String fonte) {
		this.fonte = fonte;
	}



	public String getPtres() {
		return ptres;
	}



	public void setPtres(String ptres) {
		this.ptres = ptres;
	}



	public java.util.Date getData() {
		java.util.Date dataUtil = new java.util.Date(this.data.getTime());
		return dataUtil;
	}



	public void setData(java.util.Date dataUtil) {
		java.sql.Date dataSQL = new java.sql.Date(dataUtil.getTime());
		this.data = dataSQL;
	}



	public String getElementoDespesa() {
		return elementoDespesa;
	}


	public void setElementoDespesa(String elementoDespesa) {
		this.elementoDespesa = elementoDespesa;
	}
	
	public List<ItemDetalhes> getItensDetalhesList() {
		Collection<ItemDetalhes> col = new ArrayList<ItemDetalhes>();
		if (itens!=null) {
			col =  itens.values();	
		}
		List<ItemDetalhes> list = new ArrayList<ItemDetalhes>();
		for (ItemDetalhes itemDetalhes : col) {
			list.add(itemDetalhes);
		}
		
		listaItens = list;
		
		return listaItens;
	}	
	
	public HashMap<String,ItemDetalhes> getItensDetalhesMap() {
		return itens;
	}


	public void setItensDetalhes(HashMap<String,ItemDetalhes> itens) {
		this.itens = itens;
	}
	
	public int getIdItemAtual() {
		return idItemAtual;
	}


	public void setIdItemAtual(int idItemAtual) {
		this.idItemAtual = idItemAtual;
	}


	public BigDecimal getQuantidadeItemAtual() {
		return quantidadeItemAtual;
	}


	public void setQuantidadeItemAtual(BigDecimal quantidadeItemAtual) {
		this.quantidadeItemAtual = quantidadeItemAtual;
	}


	public BigDecimal getPrecoItemAtual() {
		return precoItemAtual;
	}


	public void setPrecoItemAtual(BigDecimal precoItemAtual) {
		this.precoItemAtual = precoItemAtual;
	}

	
	public ItemDetalhes getItemDetalheSelecionado() {
		return itemDetalheSelecionado;
	}


	public void setItemDetalheSelecionado(ItemDetalhes itemDetalheSelecionado) {
		this.itemDetalheSelecionado = itemDetalheSelecionado;
	}


	public List<SelectItem> getItens(){
		List<SelectItem> itensSelectItem = new ArrayList<SelectItem>();
		List<ItemEntity> itensEntity = itemController.listarItens();
		for (ItemEntity itemEntity : itensEntity) {
			itensSelectItem.add(new SelectItem(itemEntity.getId(),"CodSIASG; "+itemEntity.getCodSIASG()+" - "+itemEntity.getDescricao()));
		}
		return itensSelectItem;
	}
	
	public String selecionarItem(){
		try {
			ItemEntity itemSelecionado = (ItemEntity) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("itemPesquisado");
			if (itemSelecionado==null) {
				throw new Exception("Nenhum item foi selecionado.");
			}
			this.especificacaoAtual=itemSelecionado.getDescricao();
			this.codSIASGAtual = itemSelecionado.getCodSIASG();
			this.unidadeAtual = itemSelecionado.getUnidade();
			this.itemEntitySelecionado = itemSelecionado;
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getMessage()));
			limparCampos();
			return "erro";
		}
		this.setItemFoiPesquisado(false);
		return "avancar";
	}
	
	public String pesquisarItemPeloNome(){
		this.itemFoiPesquisado=true;
		
		return "pesquisarItemPeloNome";
	}

	public BigDecimal getValorTotal(){
		BigDecimal total = new BigDecimal("0");
		if (itens!=null) {
			for (ItemDetalhes item : this.itens.values()) {
				BigDecimal precoItemAtual = item.getPrecoUnitario(); 
				total = total.add(precoItemAtual.multiply(item.getQuantidade()));
			}	
		}
		return total;
	}
	
	public String getValorTotalPorExtenso(){
		BigDecimal valorTotal = getValorTotal();
		Extenso extenso = new Extenso(valorTotal);
		String valorPorExtenso = "";
		if (extenso!=null) {
			valorPorExtenso=extenso.toString();
		}
		return valorPorExtenso;
	}
	
	public String adicionaItem(){
		
		if (this.itens==null) {
			this.itens=new HashMap<String,ItemDetalhes>();
		}
		try{
			if (itemEntitySelecionado==null) {
				throw new Exception("ItemSelecionado nulo.");
			}
			itemController.atualizaItemEntity(itemEntitySelecionado.getId(), especificacaoAtual, codSIASGAtual, unidadeAtual, itemEntitySelecionado.getTipo(), itemEntitySelecionado.getDataCadastramento());
			ItemDetalhes itemDetalhes = new ItemDetalhes(itemEntitySelecionado.getId(),this.quantidadeItemAtual,codSIASGAtual,especificacaoAtual,unidadeAtual,this.precoItemAtual);
		
			if (this.itens.containsKey(Integer.toString(itemDetalhes.getId()))) {
				throw new Exception("J� existe Item - "+itemEntitySelecionado.getCodSIASG()+" - com descri��o - "+itemEntitySelecionado.getDescricao()+" - incluido no pedido atual. Modifique a quantidade do Item j� incluido.");
			}
			
			this.itens.put(Integer.toString(itemDetalhes.getId()), itemDetalhes);
			
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getMessage()));
			return "erroIncluiItemPedido";
		}
			
		return "visualizaPedidoAtual";	
	}
	
	public String atualizaItem(){
		itens.remove(itemDetalheSelecionado.getId());
		ItemDetalhes novoItem = new ItemDetalhes(idItemAtual,quantidadeItemAtual,codSIASGAtual,especificacaoAtual,unidadeAtual,precoItemAtual);
		itens.put(Integer.toString(itemDetalheSelecionado.getId()), novoItem);
		
		getItensDetalhesList();
		
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Item codigo SIASG "+itemDetalheSelecionado.getCodSIASG()+" Atualizado", "ATUALIZADO "));
		return "visualizaPedidoAtual";	
	}
	
	public String preparaAtualizarItem(){
		try {
			ItemDetalhes itemSelecionado = (ItemDetalhes) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("itensAdicionados");
			if (itemSelecionado==null) {
				throw new Exception("Nenhum Item foi selecionada para altera��o.");
			}
			
			//Popular os dados da inexigibilidadeSelecionada
			idItemAtual = itemSelecionado.getId();
			especificacaoAtual = itemSelecionado.getDescricao();
			codSIASGAtual = itemSelecionado.getCodSIASG();
			unidadeAtual = itemSelecionado.getUnidade();
			quantidadeItemAtual = itemSelecionado.getQuantidade();
			precoItemAtual = itemSelecionado.getPrecoUnitario();
			itemDetalheSelecionado = itemSelecionado;
			
			
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getMessage()));
			return "erro";
		}
		return "alterarItemPedido";
	}
	
	public String removeItem(){
		ItemDetalhes itemDetalheSelecionado = (ItemDetalhes) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("itensAdicionados");
		this.itens.remove(Integer.toString(itemDetalheSelecionado.getId()));
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Removido", "Removido totalmente"));
		return "visualizaPedidoAtual";	
	}
	
	public String cadastraPedido(){
		try {
			
			pedidoController.cadastrarPedido(numPedido, processo, fonte, ptres, data, elementoDespesa);
		
		}catch (ParametroNullException e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getMessage()));
			limparCampos();
			return "erro";
		}catch (ObjetoJaCadastradoException e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getMessage()));
			limparCampos();
			return "erro";
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getMessage()));
			limparCampos();
			return "erro";
		}
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastro Realizado com Sucesso","Cadastro Realizado com Sucesso"));
		return "ok";
	}
	
	
	private void limparCampos(){
		numPedido=0;
		processo=null;
		fonte=null;
		ptres=null;
		data=new Date(System.currentTimeMillis());
		elementoDespesa=null;
		itens=null;
		
		idItemAtual=0;
		quantidadeItemAtual=null;
		precoItemAtual=null;
	}


	public void setCodSIASGAtual(String codSIASGAtual) {
		this.codSIASGAtual = codSIASGAtual;
	}


	public String getCodSIASGAtual() {
		return codSIASGAtual;
	}


	public void setItemFoiPesquisado(boolean itemFoiPesquisado) {
		this.itemFoiPesquisado = itemFoiPesquisado;
	}


	public boolean isItemFoiPesquisado() {
		return itemFoiPesquisado;
	}


	public String alteraPedido() {
		try {
			
			pedidoController.atualizaPedidoEntity(numPedido, processo, fonte, ptres, data, elementoDespesa);
			
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.toString(),e.toString()));
			limparCampos();
			return "erro";
		}
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Altera��o Realizada com Sucesso","Altera��o Realizada com Sucesso"));
		return "ok";
	}
	
	public String detalharElementoDespesa() {
		try {
			
			pedidoController.detalharElementoDespesa(numPedido, elementoDespesa);
			
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.toString(),e.toString()));
			limparCampos();
			return "erro";
		}
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Altera��o Realizada com Sucesso","Altera��o Realizada com Sucesso"));
		return "ok";
	}

	public String verificaNumeroPedido() {
		try {
			boolean pedidoExistenteEhIgual = true;
			PedidoEntity pedidoCadastrado = pedidoController.consultaPedidoEntity(numPedido);
			if (pedidoCadastrado!=null) {
				PedidoEntityPK pk = new PedidoEntityPK(numPedido,new SimpleDateFormat("yyyy").format(data));
				if (!pedidoCadastrado.equals(new PedidoEntity(pk, data,elementoDespesa,fonte, processo, ptres))) {
					pedidoExistenteEhIgual=false;
				}			
				if (!pedidoExistenteEhIgual) {
					throw new Exception("Pedido n�mero - "+numPedido+" - j� existe.");	
				}
			}
			
		} catch (Exception e) {
			editavel=false;
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.toString(),e.toString()));
			limparCampos();
			return "erro";
		}
		editavel=false;
		return "avancar";
	}
	
	public String retornarPedido() {
		editavel=false;
		return "retornar";
	}
	
	public String cancelarPedido() {
		editavel=false;
		return "cancelar";
	}
	
	public String consultaPedido() {
		try {
			
			if (numPedido<=0) {
				editavel=false;
				PedidoEntityPK pk = new PedidoEntityPK(numPedido,new SimpleDateFormat("yyyy").format(new Date(System.currentTimeMillis())));
				preecheAtributosPedido(new PedidoEntity(pk, new Date(System.currentTimeMillis()),elementoDespesa,fonte, processo, ptres));
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"N�o foi informado nenhum valor para numero de pedido.","N�o foi informado nenhum valor para numero de pedido."));
				return "";
			}else{
				PedidoEntity pedidoCadastrado = pedidoController.consultaPedidoEntity(numPedido);
				if (pedidoCadastrado!=null) {
					preecheAtributosPedido(pedidoCadastrado);
					editavel=true;
					FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Pedido n� "+numPedido+" j� existe. Clique em Avan�ar para utilizar o mesmo pedido.","Pedido n� "+numPedido+" j� existe. Clique em Avan�ar para utilizar o mesmo pedido."));
				}else{
					editavel=false;
					PedidoEntityPK pk = new PedidoEntityPK(numPedido,new SimpleDateFormat("yyyy").format(new Date(System.currentTimeMillis())));
					preecheAtributosPedido(new PedidoEntity(pk, new Date(System.currentTimeMillis()),elementoDespesa,fonte, processo, ptres));
					FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Pedido n� "+numPedido+" n�o cadastrado. Clique em Avan�ar e preecha os dados do novo pedido.","Pedido n� "+numPedido+" n�o cadastrado. Clique em Avan�ar e preecha os dados do novo pedido."));
				}
				return "avancar";
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,e.toString(),e.toString()));
			limparCampos();
			return "erro";
		}
	}

	private void preecheAtributosPedido(PedidoEntity pedidoCadastrado) {
		if (pedidoCadastrado!=null) {
			PedidoEntityPK pk = pedidoCadastrado.getId();
			this.numPedido=pk.getNumPedido();
			this.data=new java.sql.Date(pedidoCadastrado.getData().getTime());
			this.processo=pedidoCadastrado.getProcesso();
			this.fonte = pedidoCadastrado.getFonte();
			this.ptres = pedidoCadastrado.getPtres();
			this.elementoDespesa = pedidoCadastrado.getElementoDespesa();	
		}
	}


	public void setItemEntitySelecionado(ItemEntity itemEntitySelecionado) {
		this.itemEntitySelecionado = itemEntitySelecionado;
	}


	public ItemEntity getItemEntitySelecionado() {
		return itemEntitySelecionado;
	}


	public void setEspecificacaoAtual(String especificacaoAtual) {
		this.especificacaoAtual = especificacaoAtual;
	}


	public String getEspecificacaoAtual() {
		return especificacaoAtual;
	}


	public void setUnidadeAtual(String unidadeAtual) {
		this.unidadeAtual = unidadeAtual;
	}


	public String getUnidadeAtual() {
		return unidadeAtual;
	}


	public void setListaItens(List<ItemDetalhes> listaItens) {
		this.listaItens = listaItens;
	}


	public List<ItemDetalhes> getListaItens() {
		return listaItens;
	}


	public void setEditavel(boolean editavel) {
		this.editavel = editavel;
	}


	public boolean getEditavel() {
		return editavel;
	}

	
}
